package es.uned.controlador;

import es.uned.modelo.Blinky;
import es.uned.modelo.Clyde;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.LinkedList;

import javax.swing.JPanel;
import es.uned.modelo.Fantasma;
import es.uned.modelo.Mapa;
import es.uned.modelo.Pacman;
import es.uned.modelo.Pinky;
import java.awt.Color;
import java.awt.Font;
import java.awt.RenderingHints;
import java.awt.Toolkit; 

/**
 *
 * @author Gabriel Manzano Mérida Esta clase se encarga de pintar el mapa, los
 * fantasmas, la puntuación y las ventanas de diálogo.
 */
public class PacmanPanel extends JPanel {

    private Mapa mapa;
    private Pacman pacman;
    private LinkedList<Fantasma> fantasmas = new LinkedList<Fantasma>();
    private Graphics g;
    private Graphics2D g2d;
    private boolean pausa = false, intro = true;

    public PacmanPanel() {
        setFocusable(true);
        setBackground(Color.BLACK);
        setDoubleBuffered(true);
        this.mapa = new Mapa(); 
        this.pausa = false; 
    }

    /**
     * Pinta el mapa, los fantasmas, pacman y los cuadros de diálogo.
     *
     * @param g
     */
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        this.g = g;
        this.g2d = (Graphics2D) g;
        // suavizado de bordes
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        pintarMapa();

        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }

    /**
     * EL mapa será una cuadríclula de PacmanUtil(WIDTHxHEIGHT) pixeles
     *
     * @param g
     */
    private void pintarMapa() {
        pintarVidas();

        if (this.mapa != null) {
            for (int x = 0; x < PacmanUtils.COLUMNAS; x++) {
                for (int y = 0; y < PacmanUtils.FILAS; y++) {
                    pintaBloque(mapa.getElement(x, y),
                            x * PacmanUtils.WIDTH,
                            y * PacmanUtils.HEIGHT,
                            PacmanUtils.WIDTH, PacmanUtils.HEIGHT);
                }
            }
        } else {
            System.out.println("\n PacmanPanel.pintarMapa: mapa=null");
        }

        pintarPuntuacion();

        //pacman se situa en la base del mapa en el centro  
        this.pintaAPacman();

        //los fantasmas se situan en las esquinas
        this.pintaFantasmas();

        if (this.pausa) {
            pintarPausa();
        }

        if (this.pacman.isGameOver()) { 
            pintarGameOver();
        }
        
        if (this.intro){
            pintarIntro();
        }
    }

    /**
     * Mejora: pinta en el margen superior izquierdo, las vidas de pacma. No es
     * obligatorio.
     */
    private void pintarVidas() {
        //pintar vidas
        int x = 3, y = 5;
        if (this.pacman != null) {
            for (int i = 1; i <= this.pacman.getVidas(); i++) {
                g2d.drawImage(this.pacman.getImageR(), x, y, this);
                y += 35;
            } 
            if (this.pacman.getVidas() == 0) {
                g2d.drawImage(this.pacman.getImageRip(), 2, 5, this);
            }
        }
    }

    /**
     * Para cada caracter de la tabla se dibuja un elemento
     *
     * @param g
     * @param c
     * @param x
     * @param y
     * @param width
     * @param height
     */
    private void pintaBloque(char c, int x, int y, int width, int height) {

        //muro
        if (c == '1') {
            g.setColor(Color.GRAY);
            g.fillRect(x, y, width, height);
            g.setColor(Color.black);
            g.fillRect(x + 2, y + 2, width - 6, height - 6);
            g.setColor(Color.blue);
            g.fillRect(x + 3, y + 3, width - 7, height - 7);
        }
        //power pellets
        if (c == '2') {
            g.setColor(Color.orange);
            g.fillArc(x + 3, y + 3, width - 13, height - 13, 0, 360);
            g.setColor(Color.yellow);
            g.fillArc(x + 6, y + 6, width - 20, height - 20, 0, 360);
        }
        //pellets
        if (c == '3') {
            g.setColor(Color.yellow);
            g.fillArc(x + 10, y + 10, width - 25, height - 25, 0, 360);
        }
        //puerta de los fantasmas
        if (c == 'x') {
            g.setColor(Color.GREEN);
            g.fillRect(x, y + 2, width, height - 6);
        }
        //nada
        if (c == '0') { 

        }

    }

    /**
     * Pinta a Pacman en su posición en el mapa..
     */
    public void pintaAPacman() {   
         
        if (this.pacman != null) {
            g2d.drawImage(this.pacman.getImagenActual(),
                    this.pacman.getX() * PacmanUtils.WIDTH+5,
                    this.pacman.getY() * PacmanUtils.HEIGHT+5, this);
        } else {
          //  System.out.println("PacmanPanel.pintaAPacman(). Pacman=null");
        }

    }

    /**
     * Pinta a los fantasmas Blinky, Pinky y Clyde en sus posiciones y según su
     * estado.
     */
    private void pintaFantasmas() {
        if (this.fantasmas != null && !this.fantasmas.isEmpty()) {
            pintarABlinky();
            pintarAPinky();
            pintarAClyde();
        } else {
            System.out.println("\n PacmanPanel.paint: fantasmas = null o fantasmas.isEmpty()");
        }
    }

    /**
     * Pinta a Blinky en su posicion y según su estado.
     */
    private void pintarABlinky() {
        if (((Blinky) this.fantasmas.get(0)).isMiedo()) {
            g2d.drawImage(((Blinky) this.fantasmas.get(0)).getVulnerableGhostImage(),
                    ((Blinky) this.fantasmas.get(0)).getX() * PacmanUtils.WIDTH+5,
                    ((Blinky) this.fantasmas.get(0)).getY() * PacmanUtils.HEIGHT+5, this);
        } else {
            g2d.drawImage(((Blinky) this.fantasmas.get(0)).getGhostImage(),
                    ((Blinky) this.fantasmas.get(0)).getX() * PacmanUtils.WIDTH+5,
                    ((Blinky) this.fantasmas.get(0)).getY() * PacmanUtils.HEIGHT+5, this);
        }
    }

    /**
     * Pinta a Pinky en su posicion y según su estado.
     */
    private void pintarAPinky() {
        //si tiene miedo todos pasan a color morado
        if (((Pinky) this.fantasmas.get(1)).isMiedo()) {
            g2d.drawImage(((Pinky) this.fantasmas.get(1)).getVulnerableGhostImage(),
                    ((Pinky) this.fantasmas.get(1)).getX() * PacmanUtils.WIDTH+5,
                    ((Pinky) this.fantasmas.get(1)).getY() * PacmanUtils.HEIGHT+5, this);
        } else {
            g2d.drawImage(((Pinky) this.fantasmas.get(1)).getGhostImage(),
                    ((Pinky) this.fantasmas.get(1)).getX() * PacmanUtils.WIDTH+5,
                    ((Pinky) this.fantasmas.get(1)).getY() * PacmanUtils.HEIGHT+5, this);
        }
    }

    /**
     * Pinta a Clyde en su posicion y según su estado.
     */
    private void pintarAClyde() {
        //si tiene miedo todos pasan a color morado
        if (((Clyde) this.fantasmas.get(2)).isMiedo()) {
            g2d.drawImage(((Clyde) this.fantasmas.get(2)).getVulnerableGhostImage(),
                    ((Clyde) this.fantasmas.get(2)).getX() * PacmanUtils.WIDTH+5,
                    ((Clyde) this.fantasmas.get(2)).getY() * PacmanUtils.HEIGHT+5, this);
        } else {
            g2d.drawImage(((Clyde) this.fantasmas.get(2)).getGhostImage(),
                    ((Clyde) this.fantasmas.get(2)).getX() * PacmanUtils.WIDTH+5,
                    ((Clyde) this.fantasmas.get(2)).getY() * PacmanUtils.HEIGHT+5, this);
        }
    }

    /**
     * Pinta un cuadro de diálogo al finalizar el juego.
     */
    private void pintarGameOver() {
        int x = 215, y = 209, width = 410, heigth = 150;
        g.setColor(Color.GRAY);
        g.fillRect(x, y, width, heigth);
        g.setColor(Color.blue);
        g.fillRect(x + 5, y + 5, width - 10, heigth - 10);
        g.setColor(Color.yellow);

        String sGameOver = this.pacman.isWinner() ? "Bien hecho!!" : "Game over";
        String sPuntuacion = "Puntuación/Score: " + this.pacman.getPuntos();
        String sReiniciar = "Reiniciar/Restart (Pulsa R) ";
        String sSalir = "Salir/Exit (Pulsa E) ";

        Font fGameOver = new Font(sGameOver, Font.BOLD, 25);
        Font fPuntuacion = new Font(sPuntuacion, Font.BOLD, 20);
        Font fReiniciar = new Font(sReiniciar, Font.BOLD, 20);
        Font fSalir = new Font(sSalir, Font.BOLD, 20);

        g.setFont(fGameOver);
        g.drawString(fGameOver.getName(), x + 20, y + 35);

        g.setFont(fPuntuacion);
        g.drawString(fPuntuacion.getName(), x + 20, y + 65);

        g.setFont(fReiniciar);
        g.drawString(fReiniciar.getName(), x + 20, y + 95);

        g.setFont(fSalir);
        g.drawString(fSalir.getName(), x + 20, y + 125);
        
        //g2d.drawImage(this.pacman.getImageRip(), x+300, y+15, this);
        

    }

    /**
     * Pinta un cuadro de diálogo con el mensaje Pausa
     */
    private void pintarPausa() {
        int x = 240, y = 200, width = 255, heigth = 115;
        String sPausa = "Pausa";
        String sPulsaP ="(Pulsa P para volver)";
        String sSalir = "Salir/Exit (Pulsa E) ";

        Font fPausa = new Font(sPausa, Font.BOLD, 30);
        Font fPulsaP = new Font(sPulsaP, Font.PLAIN, 20);
        Font fSalir = new Font(sSalir, Font.PLAIN, 20);

        g.setColor(Color.GRAY);
        g.fillRect(x, y, width, heigth);
        g.setColor(Color.blue);
        g.fillRect(x + 5, y + 5, width - 10, heigth - 10);
        g.setColor(Color.yellow);

        g.setFont(fPausa);
        g.drawString(fPausa.getName(), x + 25, y + 35);
        
        g.setFont(fPulsaP);
        g.drawString(fPulsaP.getName(), x + 25, y + 65);

        g.setFont(fSalir);
        g.drawString(fSalir.getName(), x + 25, y + 95);

    }

    /**
     * Pinta la puntuación actualizada en una de las paredes del mapa.
     */
    private void pintarPuntuacion() {
        int x = 482, y = 562, width = 235, heigth = 35;
        g.setColor(Color.BLUE);
        g.fillRect(x, y, width, heigth);
        g.setColor(Color.YELLOW);
        g.setFont(new Font("Score", Font.BOLD, 25));
        g.drawString(Integer.toString(this.pacman.getPuntos()) + " ptos.", x + 25, 590);
    }
    
    
      private void pintarIntro() {
           
        int x = 215, y = 209, width = 410, heigth = 150;
        g.setColor(Color.GRAY);
        g.fillRect(x, y, width, heigth);
        g.setColor(Color.blue);
        g.fillRect(x + 5, y + 5, width - 10, heigth - 10);
        g.setColor(Color.yellow);

        String sIntro = "GET READY!!"; 
        String sPulsaIntro = "Pulsa Intro para comenzar. "; 

        Font fIntro = new Font(sIntro, Font.BOLD, 30); 
        Font fPulsaIntro = new Font(sPulsaIntro, Font.PLAIN, 20);

        g.setFont(fIntro);
        g.drawString(fIntro.getName(), x + 20, y + 35);

        g.setFont(fPulsaIntro);
        g.drawString(fPulsaIntro.getName(), x + 20, y + 65);
    }
    
    

    //getters & setters
    public void setMapa(Mapa mapa) {
        this.mapa = mapa;
    }

    public void setIntro(boolean intro) { 
        this.intro=intro;
    }
    public void setPausa(boolean b) {
        this.pausa = b;
    }

    public boolean isPausa() {
        return this.pausa;
    }

    public void setPacman(Pacman pacman) {
        this.pacman = pacman;
    }

    public void setFantasmas(LinkedList<Fantasma> fantasmas) {
        this.fantasmas = fantasmas;
    }

    public Graphics2D getG2d() {
        return g2d;
    }

    public Mapa getMapa() {
        return mapa;
    }

   

}
